package cn.wzr.model;

import cn.wzr.dao.iface.IModel;
import cn.wzr.dao.impl.CommodityDao;
import cn.wzr.entity.Commodity;
import cn.wzr.global.Const;
import cn.wzr.util.ActionAssistant;
import cn.wzr.util.CommonTools;
import cn.wzr.util.PropertiesMan;
import cn.wzr.util.upload.UploadImageStrategy;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

@MultipartConfig
@WebServlet("/CommodityAddAction")
public class CommodityAddAction extends HttpServlet implements IModel {

    /**
     *
     */
    private static final long serialVersionUID = -5062946478986801334L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String resultString = execute(req, resp);
        PrintWriter out = resp.getWriter();
        out.print(resultString);
    }

    @Override
    public String execute(HttpServletRequest req, HttpServletResponse resp) {
        try {
            req.setCharacterEncoding(Const.ENCODING);
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }

        boolean flag;
        // 获取前台表单提交后的
        Commodity commodity = getCommodityInfo(req, resp);
        if (null == commodity) {
            flag = false;
        } else {
            System.out.println("styleNo:" + commodity.getStyleNo());
            System.out.println("getName:" + commodity.getName());
            System.out.println("getShowNo:" + commodity.getShowNo());
            System.out.println("CmdtSN:" + commodity.getCmdtSN());

            // 获得数据库操作的DAO
            CommodityDao commodityDao = CommonTools.getCommodityDao(getServletContext().getRealPath(String.valueOf(Const.WEBURL_SEPARATOR)));
            flag = commodityDao.add(commodity);

        }

        if (flag) { // 添加成功
            return "添加成功";
        } else { // 添加失败
            return "添加失败";
        }

    }

    /**
     * 根据提交的信息生成商品对象(commodity), 同时上传（图片）文件
     *
     * @param request
     * @param response
     * @return 返回生成的商品对象(commodity)
     */
    private Commodity getCommodityInfo(HttpServletRequest request, HttpServletResponse response) {
        Commodity commodity = new Commodity();

        try {
            Collection<Part> parts = request.getParts();    // 所有前台传入的对象
            Collection<Part> uploadFiles = new ArrayList<>();    // 所有文件对象
            for (Part part : parts) {
                if (null != part.getContentType()) {
                    // 如果上传的对象为文件
                    uploadFiles.add(part);
                } else {
//                    System.out.println(part.getName() + ":" + request.getParameter(part.getName()));
                    setCommmodityValue(part.getName(), request.getParameter(part.getName()), commodity);
                }
            }

            String contextPath = getServletContext().getRealPath(String.valueOf(Const.WEBURL_SEPARATOR));
            UploadImageStrategy uploadImageStrategy = new UploadImageStrategy(contextPath);
            // 上传的相对路径,例: upload/image/17219-80/
            String imgUploadRelativePath = uploadImageStrategy.getUploadRelativePath(commodity.getStyleNo());
            String imageFolderPath = contextPath + imgUploadRelativePath;

            CommonTools.makePathDirs(imageFolderPath);
            // 防止图片文件重名,引入计数器
            short imgCount = 1;
            String longImageNames = null;
            for (Part uploadFile : uploadFiles) {
                // 将图片文件名通过间隔符连接起来(相对路径+条码-序号.扩展名), 构建图片文件名字符串(准备存入数据库)
//                System.out.println( uploadFile.getSubmittedFileName() + " ：" + uploadFile.getName());
                if(null == uploadFile || null == uploadFile.getSubmittedFileName() || uploadFile.getSubmittedFileName().isEmpty()){
                    continue;
                }

                String longImageName = imgUploadRelativePath + commodity.getCmdtSN() + Const.FILE_SUBFIX_SEPARATOR
                        + imgCount + CommonTools.getExtension(uploadFile.getSubmittedFileName());
                longImageNames = (null != longImageNames && !longImageNames.isEmpty()) ?
                        (longImageNames + Const.IMAGE_SEPARATOR + longImageName) : longImageName;
                uploadFile.write(contextPath + longImageName);    // 将上传的图片写入磁盘
                ++imgCount;
            }
            commodity.setImagePath(longImageNames);
        } catch (IOException e1) {
            e1.printStackTrace();
        } catch (ServletException e1) {
            e1.printStackTrace();
        }

        return commodity;
/*
        Enumeration enum = request.getParameterMap()
        String name = item.getFieldName().trim();
        // 解决普通输入项的数据的中文乱码问题
        String value = item.getString(Const.ENCODING).trim();
        // 每取到一对值就对commodity对象赋值
        setCommmodityValue(name, value, commodity);

        commodity.setCmdtSN(request.getParameter());
        // 消息提示
        String message = "";
*/


        /*

            for (FileItem item : list) {
                if (item.isFormField()) {


                } else {// 如果fileitem中封装的是上传文件
                    // 得到上传的文件名称
                    String filename = item.getName().trim();

                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }
                    // 注意：不同的浏览器提交的文件名是不一样的，有些浏览器提交上来的文件名是带有路径的，如：
                    // c:\a\b\1.txt，而有些只是单纯的文件名，如：1.txt
                    // 处理获取到的上传文件的文件名的路径部分，只保留文件名部分
                    filename = filename.substring(filename.lastIndexOf(File.separator) + 1);
                    // 得到上传文件的扩展名(含“.”)
                    String fileExtName = filename.substring(filename.lastIndexOf("."));
                    // 如果需要限制上传的文件类型，那么可以通过文件的扩展名来判断上传的文件类型是否合法

                    // 获取item中的上传文件的输入流
                    InputStream in = item.getInputStream();
                    // 得到文件保存的名称
                    String imgFilename = makeUploadFileName(fileExtName,imgCount++);
                    System.out.println("实际上传文件名：" + imgFilename);

                    // 得到文件的保存目录(相对路径) upload/image/2015/05/03
                    String imgUploadRelativePath = imgUploadRootPath + makeDatePath();
                    System.out.println("上传相对路径名：" + imgUploadRelativePath);

                    // 得到文件的保存目录
                    String realImgUploadPath = makeUploadFullPath(contextPath, imgUploadRelativePath);
                    System.out.println("实际上传路径：" + realImgUploadPath);
                    String realFileUploadFullPath = realImgUploadPath + imgFilename;
                    System.out.println("全路径文件名：" + realFileUploadFullPath);
                    // 创建一个文件输出流
                    FileOutputStream out = new FileOutputStream(realFileUploadFullPath);
                    // 创建一个缓冲区
                    byte buffer[] = new byte[1024];
                    // 判断输入流中的数据是否已经读完的标识
                    int len = 0;
                    // 循环将输入流读入到缓冲区当中，(len=in.read(buffer))>0就表示in里面还有数据
                    while ((len = in.read(buffer)) > 0) {
                        // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(realImgUploadPath
                        // + imgFilename)当中
                        out.write(buffer, 0, len);
                    }
                    // 关闭输入流
                    in.close();
                    // 关闭输出流
                    out.close();
                    // 删除处理文件上传时生成的临时文件
                    // item.delete();
                    String oldPath = commodity.getImagePath();
//					String imgPath = oldPath + imgUploadRelativePath + imgFilename + imgCount;
                    commodity.setImagePath(oldPath + imgUploadRelativePath + imgFilename + Const.IMAGE_SEPARATOR );
                }
            }
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            message = Const.ERRMSG_FILESIZE_OVERFLOW;

        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            message = Const.ERRMSG_ALLFILESIZE_OVERFLOW;
            System.out.println(message);
        } catch (Exception e) {
            e.printStackTrace();
            message = Const.ERRMSG_FILEUPLOAD_FAIL;
            System.out.println(message);
        }

        if(0 < message.length()){
            String msgPath = File.separator + Const.JSP_FOLDER_NAME + Const.JSP_MESSAGE;
            try {
                request.setAttribute(Const.JSP_P_MESSAGE, message);
                request.setAttribute(Const.JSP_P_FORWARD_URL, Const.JSP_PV_FORWARD_URL_BACK);
                request.setAttribute(Const.JSP_P_URL_MESSAGE, Const.JSP_PV_URLMSG_BACK);
                request.getRequestDispatcher(msgPath).forward(request, response);
                return null;
            } catch (ServletException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String oldPath = commodity.getImagePath();
        if(null != oldPath && !"".equals(oldPath)){
            if(oldPath.charAt(oldPath.length()-1) == Const.IMAGE_SEPARATOR){
                commodity.setImagePath(oldPath.substring(0,oldPath.length()-1));
            }
        }
        else{
            commodity.setImagePath("");
        }
        return commodity;
    }*/
    }


    /**
     * 通过字段名对commodity属性赋值
     *
     * @param fieldName  字段名
     * @param fieldValue
     * @param commodity
     */
    private void setCommmodityValue(String fieldName, String fieldValue, Commodity commodity) {
        if (Const.JSP_P_CMDT_ID.equalsIgnoreCase(fieldName)) {
            commodity.setId(Long.parseLong(fieldValue));
        }
        if (Const.JSP_P_CMDT_STYLENO.equalsIgnoreCase(fieldName)) {
            commodity.setStyleNo(fieldValue);
        }
        if (Const.JSP_P_CMDT_SHOWNO.equalsIgnoreCase(fieldName)) {
            commodity.setShowNo(fieldValue);
        }
        if (Const.JSP_P_CMDT_CMDTSN.equals(fieldName)) {
            commodity.setCmdtSN(fieldValue);
        }
        if (Const.JSP_P_CMDT_CMDTNAME.equals(fieldName)) {
            commodity.setName(fieldValue);
        }
//		if(Const.SQL_FD_CMDT_IMAGEPATH.equals(fieldName)){
//			commodity.setImagePath(fieldValue + Const.IMAGE_SEPARATOR);
//		}
    }


    /**
     * 根据配置文件生成上传文件时所用临时文件目录(全)路径
     *
     * @param contextPath
     * @return 成功则返回临时文件目录(全)路径
     */
    private String makeTempFullPath(String contextPath) {
        PropertiesMan pMan = new PropertiesMan(contextPath + Const.PROPERTIES_UPLOAD);
        String tmpFolder = pMan.getValue(Const.UPLOAD_TEMP_FOLDER);
        String temFullPath = tmpFolder + File.separator;
        return temFullPath;
    }

    /**
     * 根据配置文件生成图片上传总目录路径
     * （类似：upload/image/)
     *
     * @return: 成功返回图片上传总目录路径
     */
    private String getImageUploadRootPath(String contextPath) {
        return ActionAssistant.makeImageUploadPath(contextPath);
    }

    /**
     * @param fileExtName 文件的扩展名
     * @param imgIndex    图片的索引
     * @return 文件名+扩展名
     * @Description 生成上传文件的文件名：小时+分+秒+毫秒+imgIndex
     * @Anthor wzr
     */
    private String makeUploadFileName(String fileExtName, short imgIndex) {
        // 为防止文件覆盖的现象发生，要为上传文件产生一个唯一的文件名.
        SimpleDateFormat sdf = new SimpleDateFormat("HHmmssSSS");

        return sdf.format(new Date()) + imgIndex + fileExtName;
    }

    /**
     * 把工程目录路径和相对路径合并成文件上传绝对路径
     * <p> 如果目录不存在则创建
     *
     * @param uploadRelativePath 文件上传相对路径(形如：/.../upload)
     * @return 新的上传目录(全路径, 形如 ： / mydata / myPrj / upload / image / ... /)
     * @Anthor:wzr ＠param contextPath 工程目录绝对路径
     */
    private String makeUploadFullPath(String contextPath, String uploadRelativePath) {
        // 新的保存目录(绝对路径）
        String dir = contextPath + uploadRelativePath;

        makeDir(dir);
        return dir;
    }

    /**
     * 用日期构造目录路径(相对路径）
     * <p>为防止一个目录下面出现太多文件，要使用年月日分散生成目录存储
     * <p>类似2015/05/03/
     *
     * @return
     */
    private String makeDatePath() {
        String dir = (new SimpleDateFormat("yyyy")).format(new Date()) + File.separator
                + (new SimpleDateFormat("MM")).format(new Date()) + File.separator
                + (new SimpleDateFormat("dd")).format(new Date()) + File.separator;
        return dir;
    }

    private void makeDir(String dir) {
        // File既可以代表文件也可以代表目录
        File file = new File(dir);

        // 如果目录不存在
        if (!file.exists()) {
            // 创建目录
            file.mkdirs();
        }
    }
}
